package com.copyctrl.consumer.utils;

import cn.hutool.json.JSONUtil;
import com.copyctrl.campus.common.constant.RedisKind;
import com.copyctrl.campus.common.domain.RedisData;
import com.copyctrl.consumer.exception.RedisKindException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.*;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Map;

/**
 * @author:JH
 * @version:1.0
 */
@Slf4j
public class RedisUtil {
    public static<T> void saveData(RedisData<T> redisData, StringRedisTemplate stringRedisTemplate) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        RedisKind kind = redisData.getKind();
        switch (kind) {
            case SET: {
                SetOperations<String, String> ops = stringRedisTemplate.opsForSet();
                Method method = ops.getClass().getMethod(redisData.getMethodName(),redisData.getKey().getClass(), redisData.getData().getClass());
                method.setAccessible(true);
                method.invoke(ops,redisData.getKey(),redisData.getData());
                break;
            }
            case HASH: {
                /**
                 * hash数据结构所有数据都从dataMap中取
                 */
                HashOperations<String, Object, Object> ops = stringRedisTemplate.opsForHash();
                Method method = ops.getClass().getMethod(redisData.getMethodName(),Object.class, Map.class);
                method.setAccessible(true);
                method.invoke(ops,redisData.getKey(),redisData.getDataMap());
                break;
            }
            case LIST: {
                ListOperations<String, String> ops = stringRedisTemplate.opsForList();
                Method method = ops.getClass().getMethod(redisData.getMethodName(), Object.class, Collection.class);
                method.setAccessible(true);
                method.invoke(ops,redisData.getKey(),redisData.getDataList());
                break;
            }
            /**
             * 存储文章、分类存储文章
             * 决定采用dataMap处理数据，如果第一次查（这种情况其实很少） 先把数据存放在map中再去处理数据，map的key就使用时间，作为分数存入redis的zset中
             */
            case SORTEDSET:{
                ZSetOperations<String, String> ops = stringRedisTemplate.opsForZSet();
                if(redisData.getDataMap()!=null){
                    if(redisData.isUseFor()){
                        Map dataMap = redisData.getDataMap();
                        for (Object key : dataMap.keySet()) {
                            String passage = dataMap.get(key).toString();
                            Method method = ops.getClass().getMethod(redisData.getMethodName(),Object.class, Object.class,Double.TYPE);
                            method.setAccessible(true);
                            method.invoke(ops,redisData.getKey(),passage, Double.parseDouble(key.toString()));
                        }
                        break;
                    }
                }
                else if (redisData.getData()!=null){
                    Method method = ops.getClass().getMethod(redisData.getMethodName(),redisData.getKey().getClass(), redisData.getData().getClass());
                    method.setAccessible(true);
                    method.invoke(ops,redisData.getKey(),redisData.getData());
                    break;
                }
                else {
                    //处理dataList数据
                    break;
                }
            }
            case STRING:{
                ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
                Method method = ops.getClass().getMethod(redisData.getMethodName(),Object.class, Object.class);
                method.setAccessible(true);
                method.invoke(ops,redisData.getKey(),redisData.getData());
                break;

            }
            default: {
                log.error("解析redis数据出错,没有匹配的数据类型，处理数据："+redisData);
                throw new RedisKindException("解析redis数据出错,没有匹配的数据类型");
            }
        }

    }
}
